package cn.anzhiyublog.staranimegallery.controller;

import cn.anzhiyublog.staranimegallery.annotation.Auth;
import cn.anzhiyublog.staranimegallery.model.domain.Space;
import cn.anzhiyublog.staranimegallery.model.domain.User;
import cn.anzhiyublog.staranimegallery.model.dto.space.*;
import cn.anzhiyublog.staranimegallery.model.enums.Authority;
import cn.anzhiyublog.staranimegallery.model.enums.Role;
import cn.anzhiyublog.staranimegallery.model.enums.StatusCode;
import cn.anzhiyublog.staranimegallery.model.response.Response;
import cn.anzhiyublog.staranimegallery.model.vo.SpaceOnlyIdAndNameVO;
import cn.anzhiyublog.staranimegallery.model.vo.SpaceVO;
import cn.anzhiyublog.staranimegallery.service.PictureService;
import cn.anzhiyublog.staranimegallery.service.SpaceService;
import cn.anzhiyublog.staranimegallery.service.UserService;
import cn.anzhiyublog.staranimegallery.util.ResultUtils;
import cn.anzhiyublog.staranimegallery.util.ThrowUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 空间控制层
 *
 * @author 安知一只鱼
 */
@RestController
@RequestMapping("/space")
public class SpaceController {
    @Autowired
    private SpaceService spaceService;
    @Autowired
    private UserService userService;
    @Autowired
    private PictureService pictureService;

    /**
     * 创建空间
     *
     * @param spaceCreateRequest 空间创建请求
     * @param httpServletRequest HTTP请求头信息
     * @return 空间id
     */
    @Auth(value = {Authority.MANAGE, Authority.GENERAL})
    @cn.anzhiyublog.staranimegallery.annotation.Role(value = {Role.VIP, Role.ADMIN, Role.SUPER})
    @PostMapping("/create")
    public Response<Long> createSpace(@RequestBody SpaceCreateRequest spaceCreateRequest,
                                      HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(spaceCreateRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        return ResultUtils.success(spaceService.createSpace(spaceCreateRequest, userService.getLoginUser(httpServletRequest)));
    }

    /**
     * 删除空间(管理或本人)
     *
     * @param spaceDeleteRequest 空间删除请求
     * @param httpServletRequest HTTP请求头信息
     * @return 删除成功
     */
    @Auth(value = {Authority.MANAGE, Authority.GENERAL})
    @PostMapping("/delete")
    public Response<?> deleteSpace(@RequestBody SpaceDeleteRequest spaceDeleteRequest,
                                         HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(spaceDeleteRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        User loginUser = userService.getLoginUser(httpServletRequest);
        // 先删除图片再删除空间
        pictureService.deletePicturesBySpaceId(spaceDeleteRequest.getId(), loginUser);
        spaceService.deleteSpace(spaceDeleteRequest, loginUser);
        return ResultUtils.success("删除成功");
    }

    /**
     * 修改空间(仅管理员)
     *
     * @param spaceUpdateRequest 空间修改请求
     * @return 修改成功
     */
    @Auth(value = Authority.MANAGE)
    @PostMapping("/update")
    public Response<?> updateSpace(@RequestBody SpaceUpdateRequest spaceUpdateRequest) {
        ThrowUtils.throwIf(spaceUpdateRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        spaceService.updateSpace(spaceUpdateRequest);
        return ResultUtils.success("修改成功");
    }

    /**
     * 编辑空间（仅本人）
     *
     * @param spaceEditRequest 空间修改请求
     * @param httpServletRequest HTTP请求头信息
     * @return 修改成功
     */
    @Auth(value = {Authority.MANAGE, Authority.GENERAL})
    @PostMapping("/edit")
    public Response<Boolean> editSpace(@RequestBody SpaceEditRequest spaceEditRequest,
                                       HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(spaceEditRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        spaceService.editSpace(spaceEditRequest, userService.getLoginUser(httpServletRequest));
        return ResultUtils.success(true);
    }

    /**
     * id 查询空间（仅管理员或本人）
     *
     * @param spaceID 空间id
     * @param request HTTP请求头信息
     * @return 空间信息
     */
    @Auth(value = {Authority.MANAGE, Authority.GENERAL})
    @GetMapping("/get")
    public Response<SpaceVO> getSpaceById(@RequestParam long spaceID,
                                          HttpServletRequest request) {
        ThrowUtils.throwIf(spaceID <= 0, StatusCode.BAD_REQUEST, "参数错误");
        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);
        // 本人或管理员校验
        Space space = spaceService.getSpaceById(spaceID);
        boolean isSelf = space.getUserId().equals(loginUser.getId());
        boolean isManage = Authority.inManage(Role.getEnumByCode(loginUser.getRole()));
        ThrowUtils.throwIf(!isSelf && !isManage, StatusCode.FORBIDDEN);
        // 数据脱敏
        SpaceVO spaceVO = spaceService.ObjToVO(space);
        return ResultUtils.success(spaceVO);
    }

    /**
     * 分页查询空间（仅管理）
     *
     * @param spacePageQueryRequest 空间分页查询请求
     * @return 分页数据
     */
    @Auth(value = Authority.MANAGE)
    @PostMapping("/list/page")
    public Response<Page<SpaceVO>> listSpaceByPage(@RequestBody SpacePageQueryRequest spacePageQueryRequest) {
        ThrowUtils.throwIf(spacePageQueryRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        Page<Space> spacePage = spaceService.listSpaceByPage(spacePageQueryRequest);
        Page<SpaceVO> spaceVOPage = new Page<>(spacePage.getCurrent(), spacePage.getSize(), spacePage.getTotal());
        spaceVOPage.setRecords(spaceService.ObjToVO(spacePage.getRecords()));
        return ResultUtils.success(spaceVOPage);
    }

    /**
     * 查询用户名下空间(仅本人)
     *
     * @param request HTTP请求头信息
     * @return 空间列表
     */
    @Auth(value = {Authority.MANAGE, Authority.GENERAL})
    @PostMapping("/list/my-space")
    public Response<List<SpaceOnlyIdAndNameVO>> listMySpaceByPage(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        List<SpaceOnlyIdAndNameVO> vos = spaceService.listMySpaceOnlyIdAndNameVO(loginUser);
        return ResultUtils.success(vos);
    }
}
